package com.example.ibeacon_station;

import static com.example.ibeacon_station.Beacon.BEACON_TYPE_UNKNOWN;
import static com.example.ibeacon_station.Beacon.judgeBeaconType;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.Manifest;
import android.bluetooth.le.ScanResult;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Map;

public class MainActivity extends AppCompatActivity {

    private BluetoothProcess bluetoothProcess;
    private BeaconListViewModel beaconListViewModel;
    private RecyclerView recyclerView;
    private TextView beaconEnvText;
    private BeaconListAdapter beaconListAdapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        requestPermission();
        new SystemService(this);
        recyclerView = findViewById(R.id.recycleView);
        beaconEnvText = findViewById(R.id.beaconEnvironment);
        beaconListAdapter = new BeaconListAdapter();
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(beaconListAdapter);
        //添加Android自带的分割线
        recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        beaconListViewModel = new ViewModelProvider(this).get(BeaconListViewModel.class);
        beaconListViewModel.getBeaconMap().observe(this, new Observer<Map<String,Beacon>>() {
            @RequiresApi(api = Build.VERSION_CODES.N)
            @Override
            public void onChanged(Map<String,Beacon> beaconMap) {
                StringBuffer countText = new StringBuffer();
//                countText.append("扫描到有节点").append(beaconMap.size()).append("个");
                beaconEnvText.setText(countText.toString());
                beaconListAdapter.setBeaconList(new ArrayList<>(beaconMap.values()));
                beaconListAdapter.notifyDataSetChanged();
            }
        });
        bluetoothProcess = new BluetoothProcess(this);
    }

    public void beaconCallback(ScanResult result) {
        try {
            byte[] bytes = result.getScanRecord().getBytes();      // 获得广播包字节数据
            String advertisingPacket = bytesToHex(bytes);          // 转为16进制
            if (judgeBeaconType(advertisingPacket) == BEACON_TYPE_UNKNOWN) return;
            System.out.println(result);
            String mac = result.getDevice().getAddress();
            double rssi = result.getRssi();
            Beacon beacon = new Beacon(result.getDevice().getName(), mac);
            beacon.updateRSSI(rssi);
            beacon.setmUuid(advertisingPacket.substring(18, 50));
            beacon.setmMajor(Integer.parseInt(advertisingPacket.substring(50, 54), 16));
            beacon.setmMinor(Integer.parseInt(advertisingPacket.substring(54, 58), 16));
            beacon.setmTxPower(Integer.parseInt(advertisingPacket.substring(58, 60), 16) - 256);
            beaconListViewModel.addBeacon(beacon);
//            textView.setText(result.getDevice());

            // Beacon not in the main list

        } catch (Exception e) {
            Log.w("Beacon","回调出错");
            e.printStackTrace();
        }
    }

    // Permissions
    private static final int REQUEST_COARSE_LOCATION = 525;
    private static final int REQUEST_BLUETOOTH = 546;
    private static final int REQUEST_BLUETOOTH_ADMIN = 897;

    private void requestPermission() {
        if (Build.VERSION.SDK_INT >= 23) {
            int checkBluetoothPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH);
            if (checkBluetoothPermission != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.BLUETOOTH))
                    Toast.makeText(this, "动态请求权限", Toast.LENGTH_LONG).show();
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.BLUETOOTH}, REQUEST_BLUETOOTH);
            }
            int checkBluetoothAdminPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_ADMIN);
            if (checkBluetoothAdminPermission != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.BLUETOOTH_ADMIN))
                    Toast.makeText(this, "动态请求权限", Toast.LENGTH_LONG).show();
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.BLUETOOTH_ADMIN}, REQUEST_BLUETOOTH_ADMIN);
            }
            int checkCoarseLocationPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION);
            if (checkCoarseLocationPermission != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION))
                    Toast.makeText(this, "动态请求权限", Toast.LENGTH_LONG).show();
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_COARSE_LOCATION);
            }
        }
    }

    // Permission denied Alert
    private void permissionWarning() {
        new AlertDialog.Builder(this)
//                .setIcon(R.drawable.ic_warning_black_24dp)
                .setTitle("用户未授权")
                .setMessage("请手动前往【设置->应用管理->权限】中打开本软件的授权，并允许软件进行定位，再重新启动软件")
                .setNegativeButton("退出应用", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        System.exit(0);
                    }
                })
                .setCancelable(false).create().show();
    }

    // Permission result
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case REQUEST_COARSE_LOCATION: {
                if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                    permissionWarning();
                }
                BluetoothProcess.restartBluetooth();
//                else {
//                    Intent intent = getIntent();
//                    finish();
//                    startActivity(intent);
//                }
                break;
            }
            case REQUEST_BLUETOOTH: {
                if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                    permissionWarning();
                }
                break;
            }
            case REQUEST_BLUETOOTH_ADMIN: {
                if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                    permissionWarning();
                }
                break;
            }
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    /**
     * Convert bytes to Hex string.
     * e.g. transmission package analyse
     * @param bytes bytes need to convert
     * @return hex string
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte oneB : bytes) {
            String hex = Integer.toHexString(oneB & 0xFF);
            if (hex.length() == 1) hex = '0' + hex;
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }
}